package com.zxmr.domain.service;

import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.zxmr.CommonInit;
import com.zxmr.db.DBManager;
import com.zxmr.domain.account.User;
import com.zxmr.domain.component.Action;
import com.zxmr.domain.component.ActionGroup;
import com.zxmr.domain.component.Component;
import com.zxmr.domain.component.ComponentAuthorize;
import com.zxmr.domain.component.ComponentDescription;
import com.zxmr.domain.component.Page;

public class ComponentService {

	DBManager db = CommonInit.getDBManager();
	
	public boolean addComponent(ComponentDescription c)
	{
		try {
			db.getMapper().startTransaction();
			int id = (Integer)db.getMapper().insert("component.add", c.getComponent());
			c.getComponent().setId(id);
			
			if(c.getPages() != null)
			{
				for(Page page : c.getPages())
				{
					page.setComponent(id);
					db.getMapper().insert("page.add", page);
				}
			}

			addActions(c);
			
			db.getMapper().commitTransaction();
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
			
		}finally{
			try {
				db.getMapper().endTransaction();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return false;
	}
	private void addActions(ComponentDescription c) throws SQLException
	{
		List<ActionGroup> groups = c.getActions();
		if(groups == null)return;
		
		for(ActionGroup group : groups)
		{
			group.setParent(0);
			group.setComponent(c.getComponent().getId());
			addGroup(group);
		}
	}
	private void addGroup(ActionGroup actionGroup) throws SQLException
	{
		int id = (Integer)db.getMapper().insert("action.addGroup", actionGroup);
		
		if(actionGroup.getSubActions() != null)
		{
			for(Action action : actionGroup.getSubActions())
			{
				action.setComponent(actionGroup.getComponent());
				action.setGroupId(id);
				db.getMapper().insert("action.add", action);
			}
		}
		if(actionGroup.getSubGroup() != null)
		{
			for(ActionGroup group : actionGroup.getSubGroup())
			{
				group.setComponent(actionGroup.getComponent());
				group.setParent(id);
				addGroup(group);
			}
		}
		
	}
	@SuppressWarnings("unchecked")
	public List<ActionGroup> queryGroup(int company,int parent)
	{
		try
		{	
			Map<String,Integer> para = new HashMap<String,Integer>();
			para.put("company", company);
			para.put("group", parent);
			return (List<ActionGroup>)db.getMapper().queryForList("action.findGroupByParent", para);
		}catch(SQLException e)
		{
			e.printStackTrace();
		}
		return null;
	}
	/*
	public boolean deleteComponent(Component c)
	{
		try {
			DBManager.getMapper().delete("component.delete", c);
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	*/
	public boolean updateComponent(Component c)
	{
		try {
			db.getMapper().update("component.update", c);
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	public Component query(int id)
	{
		Component result = null;
		try {
			result = (Component)db.getMapper().queryForObject("component.findByID", id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	public Component query(String name)
	{
		Component result = null;
		try {
			result = (Component)db.getMapper().queryForObject("component.findByName", name);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	@SuppressWarnings("unchecked")
	public List<Component> queryAll()
	{
		List<Component> result = null;
		try {
			result = (List<Component>)db.getMapper().queryForList("component.findALL");
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public List<Component> queryPaginatedList(int start,int number)
	{
		
		List<Component> result = null;
		try {
			result = (List<Component>)db.getMapper().queryForList("component.findALL", start, number);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	/**
	 * this function used to authorize component to company, it will check if authorize has been done
	 * @param component
	 * @param employee
	 * @return
	 */
	public boolean authComponent(Component component,User employee)
	{
		if(employee == null || component == null)return false;
		int company = employee.getCompany();
		// if authorize already exist
		if(isCompanyAuthorized(company,component.getId()))
		{
			return false;
		}
		ComponentAuthorize ca = new ComponentAuthorize();
		
		ca.setAuthorizedId(generateAuthID());
		ca.setCompany(company);
		ca.setComponent(component.getId());
		Date start = new Date();
		ca.setStart(start);
		ca.setEnd(getEndDate(start,component.getDays()));
		
		try {
			db.getMapper().insert("component.authComponent", ca);
			
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	/**
	 * query all components that has been authorized to the company
	 * @param company
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Component> queryAllByCompany(int company)
	{
		List<Component> result = null;
		try {
			result = (List<Component>)db.getMapper().queryForList("component.findByCompany",company);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	public boolean isCompanyAuthorized(int company,int component)
	{
		ComponentAuthorize authorize = queryCAByCompanyAndComponent(company,component);
		if(authorize == null)return false;
		return true;
	}
	public ComponentAuthorize queryCAByCompanyAndComponent(int company,int conponent)
	{
		ComponentAuthorize ca = new ComponentAuthorize();
		ca.setCompany(company);
		ca.setComponent(conponent);
		
		ComponentAuthorize result = null;
		try {
			result = (ComponentAuthorize)db.getMapper().queryForObject("component.findCAByCompanyAndComponent", ca);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
		
	}
	public boolean addPage(Page page)
	{
		try {
			db.getMapper().insert("page.add", page);
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	public boolean updatePage(Page page)
	{
		try {
			db.getMapper().insert("page.update", page);
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	public Page findPage(int id)
	{
		try {
			return (Page)db.getMapper().queryForObject("page.findByID", id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	public List<Page> findAllPage(int component)
	{
		List<Page> result = null;
		try {
			result = (List<Page>)db.getMapper().queryForList("page.findByComponent",component);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public List<Page> findAllPageForCompany(int company)
	{
		List<Page> result = null;
		try {
			result = (List<Page>)db.getMapper().queryForList("page.findByCompany",company);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	private String generateAuthID()
	{
		return null;
	}
	private Date getEndDate(Date start,int interval)
	{
		return null;
	}
}
